﻿using System;
using NUnit.Framework;

namespace SellAndBuy.Domain.Core.Tests
{
    /// <summary>
    /// Entity Base Tests
    /// </summary>
     [TestFixture]
    public class EntityBaseTests
    {
         [Test]
         public void Creating_Entity_With_Int_ID()
         {
             var entity = new EntityIntID {SampleProperty = "Sample Value"};

             Assert.AreEqual(default(int), entity.ID);
             Assert.AreEqual("Sample Value", entity.SampleProperty);
         }

         [Test]
         public void Creating_Entity_With_Guid_ID()
         {
             var entity = new EntityGuidID { SampleProperty = "Sample Value" };

             Assert.AreEqual(default(Guid), entity.ID);
             Assert.AreEqual("Sample Value", entity.SampleProperty);
         }

         [Test]
         public void Two_Transient_Entities_Are_Not_Equals()
         {
             var entity1 = new EntityIntID { SampleProperty = "Sample Value" };
             var entity2 = new EntityIntID { SampleProperty = "Sample Value" };

             Assert.AreEqual(false, entity1.Equals(entity2));
             Assert.AreEqual(false, entity1 == entity2);
             Assert.AreEqual(true, entity1 != entity2);
         }

         [Test]
         public void Transient_Entity_Is_Not_Equal_To_Valid_Entity()
         {
             var entity1 = new EntityIntID { SampleProperty = "Sample Value" };
             var entity2 = new EntityIntID { SampleProperty = "Sample Value" };
             entity2.SetID(1);

             Assert.AreEqual(false, entity1.Equals(entity2));
             Assert.AreEqual(false, entity1 == entity2);
             Assert.AreEqual(true, entity1 != entity2);
         }

         [Test]
         public void Two_Different_Entities_Are_Not_Equals()
         {
             var entity1 = new EntityIntID();
             entity1.SetID(1);
             entity1.SampleProperty = "Sample Value";

             var entity2 = new EntityIntID();
             entity2.SetID(2);
             entity2.SampleProperty = "Sample Value";

             Assert.AreEqual(false, entity1.Equals(entity2));
             Assert.AreEqual(false, entity1 == entity2);
             Assert.AreEqual(true, entity1 != entity2);
         }

         [Test]
         public void Two_Entities_With_Same_ID_Are_Equals()
         {
             var entity1 = new EntityIntID();
             entity1.SetID(1);
             entity1.SampleProperty = "Sample Value";

             var entity2 = new EntityIntID();
             entity2.SetID(1);
             entity2.SampleProperty = "Sample Value";

             Assert.AreEqual(true, entity1.Equals(entity2));
             Assert.AreEqual(true, entity1 == entity2);
             Assert.AreEqual(false, entity1 != entity2);
         }

         [Test]
         public void Two_Null_Entities_Are_Equals()
         {
             EntityIntID entity1 = null;
             EntityIntID entity2 = null;

             Assert.AreEqual(true, entity1 == entity2);
             Assert.AreEqual(false, entity1 != entity2);
         }

         [Test]
         public void Valid_Entity_Not_Equals_To_Null_Entity()
         {
             var entity1 = new EntityIntID();
             entity1.SetID(1);
             entity1.SampleProperty = "Sample Value";

             EntityIntID entity2 = null;

             Assert.AreEqual(false, entity1.Equals(entity2));
             Assert.AreEqual(false, entity1 == entity2);
             Assert.AreEqual(true, entity1 != entity2);
         }
    }

    internal class EntityIntID : EntityBase<EntityIntID, int>
    {
        /// <summary>
        /// Set protected id
        /// </summary>
        public void SetID(int id)
        {
            ID = id;
        }

        public string SampleProperty { get; set; }
    }

    internal class EntityGuidID : EntityBase<EntityGuidID, Guid>
    {
        /// <summary>
        /// Set protected id
        /// </summary>
        public void SetID(Guid id)
        {
            ID = id;
        }

        public string SampleProperty { get; set; }
    }
}
